package com.hsyg.netty.server;

import com.hsyg.netty.server.handler.ServerHandler3;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;

/**
 * 服务端开发
 */
public class Server3 {
  private void bind(int port) {
    //配置服务端的nio线程组；
    //一个用于服务端接受客户端的连接；一个用于记性SocketChannel的网络对鞋
    EventLoopGroup bossGroup = new NioEventLoopGroup();//NioEventLoopGroup 实际就是Reactor线程池，负责调度和执行客户端的接入、网络读写事件的处理、用户自定义任务和定时任务的执行
    EventLoopGroup workGroup = new NioEventLoopGroup();

    try {

      //服务端辅助启动类，用以降低服务端的开发复杂度
      //ServerBootstrap netty用于启动nio服务端的辅助启动类，目的是降低服务端的开发复杂度
      ServerBootstrap bootstrap = new ServerBootstrap();
      bootstrap
        .group(bossGroup, workGroup)
        //实例化ServerSocketChannel
        .channel(NioServerSocketChannel.class)
        //设置ServerSocketChannel的TCP参数
        .option(ChannelOption.SO_BACKLOG, 100)
        //绑定i/0时间的处理类
        .childHandler(new ChannelInitializer<SocketChannel>() {
          @Override
          protected void initChannel(SocketChannel sc) throws Exception {
            ByteBuf delimiter = Unpooled.copiedBuffer("$_".getBytes());
            sc.pipeline().addLast(new DelimiterBasedFrameDecoder(1024, delimiter));

            sc.pipeline().addLast(new StringDecoder());
            sc.pipeline().addLast(new ServerHandler3());

          }
        });

      //绑定端口，同步等待成功 ChannelFuture：代表异步I/O的结果
      //用于异步操作的通知回调
      ChannelFuture future = bootstrap.bind(port).sync();

      //等待服务端监听端口关闭
      //等待服务端链路关闭后main函数才能推出
      future.channel().closeFuture().sync();
    } catch (Exception e) {
      System.out.println("netty Server2 服务端启动异常");
      e.printStackTrace();

    } finally {
      //优雅退出， 释放线程池资源
      workGroup.shutdownGracefully();
      bossGroup.shutdownGracefully();
    }

  }

  public static void main(String[] args) {
    int port = 8888;
    if (null != args && args.length > 0) {
      try {
        port = Integer.valueOf(args[0]);

      } catch (Exception e) {
        e.printStackTrace();
      }

    }
    new Server3().bind(port);

  }

}
